//! 处理器相关操作

use core::sync::atomic::{self, Ordering};

cfg_if::cfg_if! {
    if #[cfg(target_arch = "aarch64")] {
        mod aarch64;
        use aarch64::*;
    } else {
        mod dummy;
        use dummy::*;
    }
}

/// 获取当前 cpu 自定义 id
#[inline(always)]
pub fn this_processor_id() -> usize {
    arch_my_processor_id()
}

/// 设置当前 cpu 自定义 id
#[inline(always)]
pub fn set_this_processor_id(id: usize) {
    arch_set_my_processor_id(id);
}

/// do cpu relax
#[inline(always)]
pub fn cpu_relax() {
    arch_cpu_relax();
}

/// 最大 cpus 数量
pub const NR_CPUS: usize = 8;

/// 实际的 cpu 数量, 最大不能超过 8
#[inline(always)]
pub fn nr_cpus() -> usize {
    extern "Rust" {
        static __NR_CPUS: usize;
    }
    unsafe {
        debug_assert!(__NR_CPUS <= NR_CPUS);
        __NR_CPUS
    }
}

/// 编译器内存屏障
///
/// 阻止当前位置前后读写编译器的重排序
#[inline(always)]
pub fn barrier() {
    atomic::compiler_fence(Ordering::SeqCst);
}

/// 处理器读内存屏障
///
/// 适用于读数据操作, 防止编译器和处理器重排序读写操作到该位置之前
#[inline(always)]
pub fn smp_mb_acquire() {
    arch_smp_mb_acquire();
}

/// 处理器写内存屏障
///
/// 适用于写数据操作, 防止编译器和处理器重排序读写操作到该位置之后
#[inline(always)]
pub fn smp_mb_release() {
    arch_smp_mb_release();
}

/// 处理器写内存屏障
///
/// 同 `smp_mb_release` 一致
#[inline(always)]
pub fn smp_wmb() {
    smp_mb_release();
}

/// 处理器读内存屏障
///
/// 同 `smp_mb_acquire` 一致
#[inline(always)]
pub fn smp_rmb() {
    smp_mb_acquire();
}

/// 处理器内存屏障
///
/// 根据指定的顺序, 防止编译器和处理器围绕它重新排序某些类型的内存操作,
/// 该函数具有最严格的屏障级别
#[inline(always)]
pub fn smp_mb() {
    arch_smp_mb();
}

/// 处理器指令屏障
#[inline(always)]
pub fn isb() {
    arch_isb();
}
